<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>监听dom变化</title>
</head>
<body>
  <div id="container">
    <button id="startBtn" onclick="start()">开始监听</button>
    <button onclick="changeAttribute()">修改属性</button>
    <button onclick="addChild()">添加子节点, 然后3秒后再把这个子节点删除</button>
  </div>

  <script>
    const container = document.getElementById('container');

    function callback(mutationsList) {
      for(let item of mutationsList){
        console.log('item:',item);
        if (item.type === 'childList') {
          console.log('一个子节点被添加或删除了');
        }else if(item.type === 'attributes'){
          console.log('属性' + item.attributeName + '改变');
        }
      }
    }
    const observer = new MutationObserver(callback/** ←微任务*/);
    const config = {attributes: true, childList: true, subtree: true};
    function start(){
      observer.observe(container, config);
    }
    function changeAttribute(){
      container.setAttribute('data-name', '新的名字');
    }
    function addChild() {
      const child = document.createElement('div');
      child.innerHTML = '子节点';
      container.appendChild(child);
      setTimeout(() => {
        container.removeChild(child);
      }, 3000);
    }


    startBtn.click();

    setTimeout(() => {
      console.log('-------------宏任务-------------'); /** ←你会发现在所有插入动作触发的 MutationObserver 微任务执行完之后, 才会打印这个, 说明 MutationObserver 绑定的的确是微任务*/
    });

    for (let i = 0; i < 10000; ++i) {
      /** 为什么MutationObserver采用微任务*/
      /** 如果采用同步,这样就会执行10000次回调,执行太快,就会导致卡顿*/
      /** 如果采用异步(宏任务),会出现回调函数执行不及时的情况*/
      /** 故采用异步微任务的方式*/
      container.appendChild(document.createElement('div'));
    }

    console.log('--------------------')
  </script>
</body>
</html>
